package presentation;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;

import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.border.EmptyBorder;

import control.CControl;

public class PMonitor extends JPanel {
	private JPanel settingsPanel, graphPanel;
	private String[] layouts = {"1x2","2x2","1x3","2x3","1x4","2x4"};
	private PComboBox layoutChooser;
	private PButton saveSettingsButton, loadSettingsButton;
	private PButton showHideSettingsButton;
	private JLabel layoutLabel = new JLabel("Layout:");
	private final int MAX_PANELS = 8;
	private CControl cControl;
	private static final long serialVersionUID = 1L;
	private PGraphPanel[] graphPanels = new PGraphPanel[MAX_PANELS];
	private Color[] lineColors = {Color.blue, Color.red, Color.green, Color.black, Color.cyan, Color.magenta, Color.orange, Color.darkGray};
	private String layoutSetting;
	private boolean showSettings = true;
	private Timer saveTimer;
	private JLabel saved = new JLabel("",JLabel.CENTER);
	private final int SAVE_LABEL_VISIBLE = 1000;
	private JFileChooser fc;
	
	public PMonitor(CControl cControl) {
		this.setBackground(Color.white);
		this.setLayout(new BorderLayout());
		this.cControl = cControl;
		
		fc = new JFileChooser();
		fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
		
		ButtonListener buttonListener = new ButtonListener();
		Font buttonFont = new Font("Arial",Font.PLAIN,12);
		
		saveTimer = new Timer(SAVE_LABEL_VISIBLE,new TimerListener());
		
		// Setup graph panel:
		graphPanel = new JPanel();
		graphPanel.setBackground(Color.white);
		graphPanel.setBorder(new EmptyBorder(0, 10, 10, 10) );
		
		saved.setFont(buttonFont);
		saved.setPreferredSize(new Dimension(200,20));
		
		// Setup settings panel:
		saveSettingsButton = new PButton("Save settings",buttonListener,buttonFont);
		saveSettingsButton.setPreferredSize(new Dimension(130,20));
		
		loadSettingsButton = new PButton("Load settings",buttonListener,buttonFont);
		loadSettingsButton.setPreferredSize(new Dimension(130,20));
		
		layoutLabel.setFont(new Font("Arial",Font.PLAIN,12));
		layoutLabel.setForeground(Color.black);
		
		layoutChooser = new PComboBox(layouts,new ComboBoxListener(),buttonFont);
		layoutChooser.setPreferredSize(new Dimension(50,20));
		
		showHideSettingsButton = new PButton("Hide graph settings",buttonListener,buttonFont);
		showHideSettingsButton.setPreferredSize(new Dimension(150,20));
		
		settingsPanel= new JPanel();
		settingsPanel.setPreferredSize(new Dimension(0,30));
		settingsPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
		settingsPanel.setBackground(Color.white);
		settingsPanel.add(saved);
		settingsPanel.add(showHideSettingsButton);
		settingsPanel.add(layoutLabel);
		settingsPanel.add(layoutChooser);
		settingsPanel.add(saveSettingsButton);
		settingsPanel.add(loadSettingsButton);
		
		setGraphPanels();
	}
	
	private void setGraphPanels() {
		layoutSetting = cControl.getGraphSettingsParameter("monitorlayout");
		generateGraphPanels();
		setGraphLayout(layoutSetting);
		
		String showSettingsParameter = cControl.getGraphSettingsParameter("monitorshowsettings");
		if (showSettingsParameter != null && showSettingsParameter.equalsIgnoreCase("false")) {
			showHideSettingsButton.setText("Show graph settings");
			showSettings = false;
			for (int i = 0; i < MAX_PANELS; i++) {
				graphPanels[i].showSettings(false);
			}
		}
		
		// Setup monitor panel:
		this.add(settingsPanel, BorderLayout.PAGE_START);
		this.add(graphPanel, BorderLayout.CENTER);
		layoutChooser.setSelectedItem(layoutSetting);
	}
	
	private void setGraphLayout(String layoutFormat) {
		int x, y;
		try {
			x = Integer.parseInt(layoutFormat.substring(0,1));
			y = Integer.parseInt(layoutFormat.substring(2,3));
		} catch (NumberFormatException nfe) {
			x = 2;
			y = 4;
			layoutSetting = "2x4";
		} catch (NullPointerException npe) {
			x = 2;
			y = 4;
			layoutSetting = "2x4";
		}
		
		graphPanel.removeAll();
		graphPanel.setLayout(new GridLayout(y,x,10,10));
		
		for (int i = 0; i < x*y; i++) {
			graphPanel.add(graphPanels[i]);
		}
		
		this.updateUI();
	}
	
	private void generateGraphPanels() {
		String[] plotableRegisters = cControl.getPlotableRegisters();
		
		for (int i = 0; i < MAX_PANELS; i++) {
			graphPanels[i] = new PGraphPanel(plotableRegisters,lineColors[i],i,cControl);
		}
	}
	
	private class ComboBoxListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent ae) {
			String selection = layouts[layoutChooser.getSelectedIndex()];
			setGraphLayout(selection);
		}
	}
	
	private class ButtonListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent ae) {
			if (ae.getSource() == saveSettingsButton) {
				boolean success = true;
				int returnVal = fc.showSaveDialog(PMonitor.this);
	            if (returnVal == JFileChooser.APPROVE_OPTION) {
	                File file = fc.getSelectedFile();
	                if (!cControl.setGraphSettingsFile(file.getAbsolutePath())) {
	                	success = false;
	                } else {
	                	if (!cControl.setGraphSettingsParameter("monitorshowsettings", showSettings + "")) {
	    					success = false;
	    				}
	    				if (!cControl.setGraphSettingsParameter("monitorlayout", (String) layoutChooser.getSelectedItem())) {
	    					success = false;
	    				}
	    				for (int i = 0; i < MAX_PANELS; i++) {
	    					if (!cControl.setGraphSettingsParameter("monitorgraph" + i + "value", graphPanels[i].getSelectedValue())) {
	    						success = false;
	    					}
	    					if (!cControl.setGraphSettingsParameter("monitorgraph" + i + "samples", graphPanels[i].getSampleCountValue() + "")) {
	    						success = false;
	    					}
	    				}
	                }
	                
	                if (success) {
						saved.setText("Saved...");
						saved.setForeground(Color.black);
						saveTimer.start();
					} else {
						saved.setText("Unable to save. Check log.");
						saved.setForeground(Color.red);
						saveTimer.start();
					}
	            }
			} else if (ae.getSource() == loadSettingsButton) {
				int returnVal = fc.showOpenDialog(PMonitor.this);

	            if (returnVal == JFileChooser.APPROVE_OPTION) {
	            	boolean success = true;
	                File file = fc.getSelectedFile();
	                if (!cControl.setGraphSettingsFile(file.getAbsolutePath())) {
	                	success = false;
	                } else {
	                	setGraphPanels();
	                }
	                
	                if (success) {
						saved.setText("Loaded...");
						saved.setForeground(Color.black);
						saveTimer.start();
					} else {
						saved.setText("Unable to load file. Check log.");
						saved.setForeground(Color.red);
						saveTimer.start();
					}
	                
	            }
			} else if (ae.getSource() == showHideSettingsButton) {
				showSettings = !showSettings;
				String settingsButtonText = (showSettings) ? "Hide graph settings" : "Show graph settings";
				showHideSettingsButton.setText(settingsButtonText);
				
				for (int i = 0; i < MAX_PANELS; i++) {
					graphPanels[i].showSettings(showSettings);
				}
			}
		}
	}
	
	private class TimerListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			if (e.getSource() == saveTimer) {
				saveTimer.stop();
				saved.setText("");
			}
		}
	}
}
